package com.eugenema.handler;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.eugenema.entity.FutureMatch;
import com.eugenema.entity.TestStep;
import com.eugenema.util.ConfigUtil;
import com.eugenema.util.ExcelUtil.CustomColumnWidth;
import com.eugenema.util.SeleniumXmlParseUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.List;

/**
 * 处理 Excel 处理器
 * <br/>所有文件均在 resources/excel 路径下
 *
 * @author Eugenema
 * @date 2023/3/13 21:57
 */
public class ExcelActionHandler {
    private Logger logger = LoggerFactory.getLogger(ExcelActionHandler.class);

    /**
     * 写 Excel
     * <br/>将全局存储 map（SeleniumUtil.globalMap）中指定数据写入到 Excel
     * <br/>若指定文件存在，则会先删除
     *
     * @author Eugenema
     * @date 2023/3/13 21:58
     *
     * @param testStep 动作
     *
     **/
    public void writeExcel(TestStep testStep) throws Exception {
        File outPutFile = new File(ConfigUtil.getProperty(ConfigUtil.EXCEL_OUTPUT_PATH) + testStep.getOperationFileName());
        if (outPutFile.exists()) {
            logger.info("文件【{}】已存在，将删除该文件", outPutFile.getAbsolutePath());
            outPutFile.delete();
        }

        //创建构造器
        ExcelWriterBuilder excelWriterBuilder;
        if (testStep.getExcelEntity() != null) {
            excelWriterBuilder = EasyExcel.write(outPutFile, testStep.getExcelEntity());
        } else {
            excelWriterBuilder = EasyExcel.write(outPutFile);
        }

        //注册样式处理器
        if (StringUtils.isNotBlank(testStep.getWriteCellStyleListEL())) {
            List writeCellStyleList = SeleniumXmlParseUtil.parseEL(testStep.getWriteCellStyleListEL(), List.class);
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(null, writeCellStyleList);
            excelWriterBuilder.registerWriteHandler(horizontalCellStyleStrategy);
        }

        //注册自定义列宽处理器
        if (StringUtils.isNotBlank(testStep.getCustomColumn())) {
            String[] split = testStep.getCustomColumn().split(",");
            excelWriterBuilder.registerWriteHandler(new CustomColumnWidth(Integer.valueOf(split[0]), Integer.valueOf(split[1])));
        }

        //加载模板文件
        if (StringUtils.isNotBlank(testStep.getTemplateFileName())) {
            File templateExcelFile = new File(ConfigUtil.getProperty(ConfigUtil.EXCEL_TEMPLATE_PATH) + testStep.getTemplateFileName());
            if (!templateExcelFile.exists()) {
                throw new RuntimeException(String.format("模板文件【%s】不存在", templateExcelFile.getAbsolutePath()));
            }
            excelWriterBuilder.withTemplate(templateExcelFile);
        }

        //读取 sheet
        ExcelWriterSheetBuilder excelWriterSheetBuilder = excelWriterBuilder.sheet(testStep.getSheetName());

        //写入 Excel
        /** 要写入的数据 */
        List dealList = SeleniumXmlParseUtil.parseEL(testStep.getDataListEL(), List.class);
        if (StringUtils.isNotBlank(testStep.getTemplateFileName())) {
            excelWriterSheetBuilder.doFill(dealList);
        } else {
            excelWriterSheetBuilder.doWrite(dealList);
        }
        logger.info("文件【{}】导出完成", outPutFile.getAbsolutePath());
    }

    /**
     * 读 Excel
     * <br/>默认支持超链接的读取，监听器中可以对获取到的超链接进行处理
     *
     * @author Eugenema
     * @date 2023/3/13 22:42
     *
     * @param testStep 动作
     *
     **/
    public void readExcel(TestStep testStep) {
        File readFile = new File(ConfigUtil.getProperty(ConfigUtil.EXCEL_OUTPUT_PATH) + testStep.getOperationFileName());
        if (!readFile.exists()) {
            throw new RuntimeException(String.format("读取的文件【%s】不存在", readFile.getAbsolutePath()));
        }
        EasyExcel.read(readFile, FutureMatch.class, testStep.getReadListener())
        .extraRead(CellExtraTypeEnum.HYPERLINK)
        .sheet(testStep.getSheetName()).doRead();
    }
}
